package tcplib

import (
	"bytes"
	"cow_golang/shared_mod/tcplib/iface"
	"encoding/binary"
	"errors"
	"fmt"
)

type MessagePack struct{}

func NewMessagePack() *MessagePack {
	return &MessagePack{}
}

// GetHeadLen 获取包头长度
func (m *MessagePack) GetHeadLen() uint32 {
	// DataLen unit32 4 + Id uint32 4
	return 8
}

// Pack 封包
func (m *MessagePack) Pack(msg iface.IMessage) ([]byte, error) {
	// 创建buff
	dataBuff := bytes.NewBuffer([]byte{})
	// 写buff
	// 1 写data长度
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetDataLen()); err != nil {
		return nil, err
	}
	// 2 写入消息id
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgId()); err != nil {
		return nil, err
	}
	// 3 写入消息内容
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}
	fmt.Println("send msg id:", msg.GetMsgId(),
		" len:", msg.GetDataLen(),
		" data:", string(msg.GetData()))
	return dataBuff.Bytes(), nil
}

// UnPack 解包
func (m *MessagePack) UnPack(binaryData []byte) (iface.IMessage, error) {
	// io reader
	dataBuff := bytes.NewReader(binaryData)
	// 创建消息
	msg := &Message{}
	// 读取buff
	// 1 读取data长度
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}
	// 2 读取消息id
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.Id); err != nil {
		return nil, err
	}
	// 3 读取消息内容
	if msg.GetDataLen() > MaxPacketSize {
		return nil, errors.New("message too long")
	}

	return msg, nil
}
